package com.jifeng.api.wxpay.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jifeng.api.crud.constant.FieldConstant;
import com.jifeng.api.crud.entity.OrderEntity;
import com.jifeng.api.crud.entity.TerminalEntity;
import com.jifeng.api.crud.service.OrderService;
import com.jifeng.api.crud.service.TerminalService;
import com.jifeng.api.crud.utils.CheckParamsRs;
import com.jifeng.api.utils.R;
import com.jifeng.api.vo.ReqWxPayVo;
import com.jifeng.api.wxpay.controller.AppletPayUtil;
import com.jifeng.api.wxpay.controller.PayService;
import com.jifeng.api.wxpay.service.WXPayService;
import com.jifeng.api.wxpay.utils.IdGen;
import com.jifeng.api.wxpay.utils.WxPhoneUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service("wXPayService")
@Slf4j
public class WXPayServiceImpl implements WXPayService {

    @Autowired
    private PayService payService;

    @Autowired
    OrderService orderService;

    @Autowired
    CheckParamsRs checkParamsRs;

    @Autowired
    TerminalService terminalService;

    @Override
    public R wxPay(ReqWxPayVo params) {
        String terminalId = "";
        try {
            terminalId = params.getTerminalId();
            String mobile = params.getMobile();
            String openId = params.getOpenId();
//            int money = params.getAmount();
            String outTradeNo = params.getNumber();

            log.info("path：{}，ReqWxPayVo：{}", getRequestUrl(), params);

            /**
             * 校验 机柜编号 和 手机号格式
             */
            boolean checkIotAndMobileRs = checkParamsRs.checkIotAndMobile(terminalId, mobile);
            if (!checkIotAndMobileRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "机柜编号或手机号格式错误");
                return R.error("机柜编号或手机号格式错误");
            }

            /**
             * 查询订单信息
             */
            OrderEntity orderEntity = orderService.getById(outTradeNo);
            if (orderEntity == null) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "订单不存在");
                return R.error("订单不存在");
            }

            // 需要支付的费用
            Integer fee = orderEntity.getFee();

            /**
             * 统一下单
             */
            R rs = payService.unifiedOrder(outTradeNo, fee, openId, terminalId, mobile);
//            R rs = payService.unifiedOrder(outTradeNo, new BigDecimal(fee), openId, terminalId, mobile);
            return rs;
        } catch (Exception e) {
            TerminalEntity terminalEntity = new TerminalEntity();
            terminalEntity.setRentState(0);
            boolean update = terminalService.update(terminalEntity,new UpdateWrapper<TerminalEntity>().eq(FieldConstant.T_TERMINAL_IOT,terminalId));
            if (!update) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "更新机柜状态失败");
                // TODO: 2020/9/26 往更新失败表插入记录
            }
            e.printStackTrace();
            log.error("path：{}，errMsg：{}", getRequestUrl(), e.getMessage());
            return R.sysError();
        }
    }

    @Override
    public R pay(ReqWxPayVo params) {
        String terminalId = "";
        try {
            terminalId = params.getTerminalId();
            String mobile = params.getMobile();
            String openId = params.getOpenId();
//            int money = params.getAmount();
            String orderId = params.getNumber();


            /**
             * 校验 机柜编号 和 手机号格式
             */
            boolean checkIotAndMobileRs = checkParamsRs.checkIotAndMobile(terminalId, mobile);
            if (!checkIotAndMobileRs) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "机柜编号或手机号格式错误");
                return R.error("机柜编号或手机号格式错误");
            }

            /**
             * 查询订单信息
             */
            OrderEntity orderEntity = orderService.getById(orderId);
            if (orderEntity == null) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "订单不存在");
                return R.error("订单不存在");
            }

            // 需要支付的费用
            Integer fee = orderEntity.getFee();
            Integer paidFee = orderEntity.getPaidFee();
            Integer finalFee = fee;
            if (fee > paidFee) {
                finalFee = fee - paidFee;
            } else {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "不需要缴纳额外的费用");
                return R.error("不需要缴纳额外的费用");
            }

            //订单号  uuid
            String outTradeNo= IdGen.uuid();

            /**
             * 统一下单
             */
            R rs = payService.endUnifiedOrder(outTradeNo, finalFee, openId, terminalId, mobile,orderId);
//            R rs = payService.endUnifiedOrder(outTradeNo, new BigDecimal(finalFee), openId, terminalId, mobile,orderId);
            return rs;
        } catch (Exception e) {
            TerminalEntity terminalEntity = new TerminalEntity();
            terminalEntity.setRentState(0);
            boolean update = terminalService.update(terminalEntity,new UpdateWrapper<TerminalEntity>().eq(FieldConstant.T_TERMINAL_IOT,terminalId));
            if (!update) {
                log.warn("path：{}，errMsg：{}", getRequestUrl(), "更新机柜状态失败");
                // TODO: 2020/9/26 往更新失败表插入记录
            }
            e.printStackTrace();
            log.error("path：{}，errMsg：{}", getRequestUrl(), e.getMessage());
            return R.sysError();
        }
    }


    @Override
    public R getOpenId(Map<String, Object> params) {
        try {
            Map<String, Object> rsMap = new HashMap<>();
            String code = params.get("code").toString();
            String decryptData = params.get("decryptData").toString();
            String iv = params.get("iv").toString();

            /**
             * 根据code获取openId
             */
            Map<String, Object> map = AppletPayUtil.getOpenIdByCode(code);
            if (map.isEmpty()) {
                log.warn("path：{}，errMsg：{}", "微信支付（租赁完成）", "用户凭证无效");
                return R.error("用户凭证无效");
            }
            String phone = WxPhoneUtil.getPhoneNumberBeanS5(decryptData, map.get("sessionKey").toString(), iv);
            rsMap.put("openId", map.get("openId"));
            rsMap.put("phone", phone);
            return R.ok().put("data", rsMap);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("path：{}，errMsg：{}", "获取openId", e.getMessage());
            return R.sysError();
        }
    }

    public String getRequestUrl() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest().getRequestURI();
    }
}
